package com.ding.authorizationserver.config

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer
import org.springframework.security.oauth2.provider.token.TokenStore
import org.springframework.security.web.header.HeaderWriter

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@Configuration
@EnableResourceServer
class ResourceServerConfig implements ResourceServerConfigurer{

    @Autowired
    TokenStore tokenStore

    /*
        资源访问拦截配置
     */
    @Override
    void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
                .and()
                .requestMatchers().antMatchers('/data/**')
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET,"/data/**").access("#oauth2.hasScope('all')")
                .and()
                .headers().addHeaderWriter(new HeaderWriter() {
            @Override
            public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
                response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
            }
        });

    }

    /*
        资源服务配置
     */
    @Override
    void configure(ResourceServerSecurityConfigurer resources) throws Exception {

        /*
            配置令牌存储
            tokenStore  资源服务通过该令牌存储验证客户端提供的令牌是否有效
            stateless   是否是无状态服务
            resourceId  表示在授权后允许访问的资源

         */
        resources
                .tokenStore(tokenStore)
                .stateless(true)
                .resourceId('a')
                .resourceId('b')
    }
}

/*
    无状态服务:对单次请求的处理，不依赖其他请求，也就是说，处理一次请求所需的全部信息，要么都包含在这个请求里，要么可以从外部获取到（比如说数据库），服务器本身不存储任何信息.使用无状态服务就以为着只能使用令牌访问这些资源
 */